package com.zhao.fishingguideserver.aspect;

import com.zhao.fishingguideserver.POJO.OperationLog;
import com.zhao.fishingguideserver.annotation.AdminOperation;
import com.zhao.fishingguideserver.service.OperationLogService;
import com.zhao.fishingguideserver.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.StringJoiner;

@Aspect
@Component
public class AdminOperationLogAspect {

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private HttpServletRequest request;

    @Pointcut("@annotation(adminOperation)")
    public void adminOpPointcut(AdminOperation adminOperation) {}

    @AfterReturning(pointcut = "adminOpPointcut(adminOperation)", returning = "ret")
    public void afterReturning(JoinPoint joinPoint, AdminOperation adminOperation, Object ret) {
        try {
            Map<String, Object> claims = ThreadLocalUtil.get();
            if (claims == null || claims.get("adminId") == null) {
                // 仅记录管理员操作
                return;
            }
            Long adminId = ((Number) claims.get("adminId")).longValue();
            String adminName = String.valueOf(claims.getOrDefault("username", ""));

            OperationLog log = new OperationLog();
            log.setAdminId(adminId);
            log.setAdminName(adminName);
            log.setOperationModule(adminOperation.module());
            log.setOperationType(adminOperation.type());
            log.setIpAddress(getClientIp(request));

            // 生成简单参数摘要
            StringJoiner argsJoiner = new StringJoiner(", ");
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                if (arg == null) continue;
                String s = arg.toString();
                if (s.length() > 200) {
                    s = s.substring(0, 200) + "...";
                }
                argsJoiner.add(s);
            }
            String detail = adminOperation.detail();
            if (detail == null || detail.isEmpty()) {
                detail = joinPoint.getSignature().toShortString() + " args=[" + argsJoiner + "]";
            }
            log.setOperationDetail(detail);

            operationLogService.addLog(log);
        } catch (Exception ignored) {
            // 审计不影响主流程
        }
    }

    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }
}


